/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mycompany.delivery.service;

import com.mycompany.delivery.dao.ContactDAO;
import com.mycompany.delivery.dao.DeliveryDAO;
import com.mycompany.delivery.dto.ContactDTO;
import com.mycompany.delivery.dto.DeliveryDTO;
import com.mycompany.delivery.dto.UserDTO;
import com.mycompany.delivery.entities.Contact;
import com.mycompany.delivery.entities.Delivery;
import com.mycompany.delivery.servicelayer.ContactService;
import com.mycompany.delivery.servicelayer.UserService;
import com.mycompany.delivery.transfers.ContactT;
import com.mycompany.delivery.transfers.DeliveryT;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author Jana Nemcova
 */
@Service("contactServices")
public class ContactServiceImpl implements ContactService {

    @Autowired
    private ContactDAO contactDao;

    @Autowired
    private DeliveryDAO deliveryDao;

    @Autowired
    private UserService userService;

    public UserService getUserService() {
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public ContactDAO getContactDao() {
        return contactDao;
    }

    public void setContactDao(ContactDAO contactDao) {
        this.contactDao = contactDao;
    }

    public DeliveryDAO getDeliveryDao() {
        return deliveryDao;
    }

    public void setDeliveryDao(DeliveryDAO deliveryDao) {
        this.deliveryDao = deliveryDao;
    }

    @Override
    @Transactional
   @Secured({"ROLE_EMPL", "ROLE_ADMIN"})
    public ContactDTO create(ContactDTO p) {
        if (p == null) {
            throw new IllegalArgumentException("contact is null");
        }
        if (p.getId() != null) {
            throw new IllegalArgumentException("id must be null");
        }

        Contact c = ContactT.dTOtoEntity(p);
        contactDao.createContact(c);
        p.setId(c.getId());
        return p;
    }

    @Override
    @Transactional
    @Secured({"ROLE_EMPL","ROLE_ADMIN"})
    public ContactDTO update(ContactDTO p) {
        if (p == null) {
            throw new IllegalArgumentException("contact is null");
        }
        if (p.getId() == null) {
            throw new IllegalArgumentException("id can't be null");
        }
        contactDao.updateContact(ContactT.dTOtoEntity(p));
        return p;
    }

    @Override
    @Transactional
    @Secured({"ROLE_EMPL",  "ROLE_ADMIN"})
    public ContactDTO remove(ContactDTO p) {
        if (p == null) {
            throw new IllegalArgumentException("contact is null");
        }
        if (p.getId() == null) {
            throw new IllegalArgumentException("id cant be null");
        }

        List<Delivery> deliveries = deliveryDao.getDeliveriesByReceiver(ContactT.dTOtoEntity(p));
        for (Delivery del : deliveries) {
            del.setReceiver(null);
            deliveryDao.updateDelivery(del);
        }

        deliveries = deliveryDao.getDeliveriesBySender(ContactT.dTOtoEntity(p));
        for (Delivery del : deliveries) {
            del.setSender(null);
            deliveryDao.updateDelivery(del);
        }

        List<UserDTO> users = userService.getAllCouriers();
        for (UserDTO user : users) {
            if (user.getContact() != null) {
                if (Objects.equals(user.getContact().getId(), p.getId())) {
                    user.setContact(null);
                    userService.updateCourier(user);
                }
            }
        }

        users = userService.getAllEmployees();
        for (UserDTO user : users) {
            if (user.getContact() != null) {
                if (Objects.equals(user.getContact().getId(), p.getId())) {
                    user.setContact(null);
                    userService.updateEmployee(user);
                }
            }
        }

        contactDao.deleteContact(ContactT.dTOtoEntity(p));
        return p;
    }

    @Override
    @Transactional
    @Secured({"ROLE_EMPL", "ROLE_COUR", "ROLE_ADMIN"})
    public ContactDTO find(Long id
    ) {
        if (id == null) {
            throw new IllegalArgumentException("id is null");
        }
        return ContactT.entityToDTO(contactDao.getContactById(id));

    }

    @Override
    @Transactional
    @Secured({"ROLE_EMPL", "ROLE_COUR", "ROLE_ADMIN"})
    public List<ContactDTO> findContactBySurname(String name
    ) {
        if (name == null) {
            throw new IllegalArgumentException("name is null");
        }
        List<ContactDTO> list = new ArrayList<ContactDTO>();
        for (Contact item : contactDao.getContactBySurname(name)) {
            list.add(ContactT.entityToDTO(item));
        }

        return list;
    }

    @Override
    @Transactional
    @Secured({"ROLE_EMPL", "ROLE_COUR", "ROLE_ADMIN"})
    public List<DeliveryDTO> findDeliveriesBySender(ContactDTO contact
    ) {
        if (contact == null) {
            throw new IllegalArgumentException("contact is null");
        }
        if (contact.getId() == null) {
            throw new IllegalArgumentException("id cant be null");
        }
        List<DeliveryDTO> list = new ArrayList<DeliveryDTO>();

        for (Delivery item : deliveryDao.getDeliveriesBySender(ContactT.dTOtoEntity(contact))) {
            list.add(DeliveryT.EntityToDTO(item));
        }

        return list;

    }

    @Override
    @Transactional
    @Secured({"ROLE_EMPL", "ROLE_COUR", "ROLE_ADMIN"})
    public List<DeliveryDTO> findDeliveriesByReceiver(ContactDTO contact
    ) {
        if (contact == null) {
            throw new IllegalArgumentException("contact is null");
        }
        if (contact.getId() == null) {
            throw new IllegalArgumentException("id cant be null");
        }
        List<DeliveryDTO> list = new ArrayList<DeliveryDTO>();
        for (Delivery item : deliveryDao.getDeliveriesByReceiver(ContactT.dTOtoEntity(contact))) {
            list.add(DeliveryT.EntityToDTO(item));
        }

        return list;
    }

    @Override
    @Transactional
    @Secured({"ROLE_EMPL", "ROLE_COUR", "ROLE_ADMIN"})
    public List<ContactDTO> getAllContacts() {
        List<ContactDTO> contacts = new ArrayList<>();
        for (Contact c : contactDao.getAllContacts()) {
            contacts.add(ContactT.entityToDTO(c));
        }

        return contacts;
    }
}
